package com.gson.util;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class JodaTime {

	public void convertToString() {
		String format = "yyyy-MM-dd HH:mm:ss";
		DateTime fooDate = new DateTime(1978, 6, 1, 12, 10, 8, 0);
		// 第一种方法 直接使用DateTime的toString方法
		System.out.println(fooDate.toString(format));

		// 第二种方法,使用Formatter
		DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
		System.out.println(fmt.print(fooDate));
	}

	public void convertFromString() {
		String dateString = "1978-06-01 12:10:08";
		DateTimeFormatter fmt = DateTimeFormat
				.forPattern("yyyy-MM-dd HH:mm:ss");
		// 第一种方法，直接构造函数,注意日期和时间之间用T分割
		DateTime dt1 = new DateTime("1978-06-01");
		// assertEquals(1978, dt1.getYear());
		DateTime dt2 = new DateTime("1978-06-01T12:10:08");
		// assertEquals(1978, dt2.getYear());

		// 第二种方法，使用Formatter
		DateTime dt3 = fmt.parseDateTime(dateString);
		// assertEquals(1978, dt3.getYear());

	}

	public void timeZone() {

		System.out.println("演示时区");

		String format = "yyyy-MM-dd HH:mm:ss zZZ";

		// DateTime的毫秒即System的毫秒,即1970到现在的UTC的毫秒数.
		System.out.println(new DateTime().getMillis() + " "
				+ System.currentTimeMillis());

		// 将日期按默认时区打印
		DateTime fooDate = new DateTime(1978, 6, 1, 12, 10, 8, 0);
		System.out
				.println(fooDate.toString(format) + " " + fooDate.getMillis()); // "1978-06-01
																				// 12:10:08"

		// 将日期按UTC时区打印
		DateTime zoneWithUTC = fooDate.withZone(DateTimeZone.UTC);
		System.out.println(zoneWithUTC.toString(format) + " "
				+ zoneWithUTC.getMillis());// "1978-06-01 04:10:08",
		// sameMills

		// 按不同的时区分析字符串,得到不同的时间
		String dateString = "1978-06-01 12:10:08";
		DateTimeFormatter fmt = DateTimeFormat
				.forPattern("yyyy-MM-dd HH:mm:ss");

		DateTime parserResult1 = fmt.withZone(DateTimeZone.forID("US/Pacific"))
				.parseDateTime(dateString);
		DateTime parserResult2 = fmt.withZoneUTC().parseDateTime(dateString);

		System.out.println(parserResult1.toString(format) + " "
				+ parserResult1.getMillis());
		System.out.println(parserResult2.toString(format) + " "
				+ parserResult2.getMillis());
	}

	/**
	 * 打印当地语言年，月，日到写法
	 */

	public static String getNowTime() {
		return getNowTime(null);
	}

	public static String getNowTime(String format) {
		if (org.apache.commons.lang3.StringUtils.isEmpty(format)) {
			format = "yyyy-MM-dd HH:mm:ss";
		}
		DateTime dateTime = new DateTime();

		return dateTime.toString(format);
	}

	public static void main(String[] args) {
		System.out
				.println(getNextDay(getNowTime("yyyy-MM-dd"), 51));
	}

	public static void locale() {

		System.out.println("演示Locale");

		DateTime dateTime = new DateTime().withZone(DateTimeZone.UTC);

		// 打印中文与英文下不同长度的日期格式串
		System.out.println("S:  " + formatDateTime(dateTime, "SS", "zh"));
		System.out.println("M:  " + formatDateTime(dateTime, "MM", "zh"));
		System.out.println("L:  " + formatDateTime(dateTime, "LL", "zh"));
		System.out.println("XL: " + formatDateTime(dateTime, "FF", "zh"));
		System.out.println("");

		System.out.println("S:  " + formatDateTime(dateTime, "SS", "en"));
		System.out.println("M:  " + formatDateTime(dateTime, "MM", "en"));
		System.out.println("L:  " + formatDateTime(dateTime, "LL", "en"));
		System.out.println("XL: " + formatDateTime(dateTime, "FF", "en"));
		System.out.println("");
		System.out.println("");

		// 直接打印TimeStamp, 日期是M,时间是L
		DateTimeFormatter formatter = DateTimeFormat.forStyle("ML").withLocale(
				new Locale("zh")).withZone(DateTimeZone.UTC);

		System.out.println("ML Mix: " + formatter.print(dateTime.getMillis()));

		// 只打印日期不打印时间
		System.out
				.println("Date only :" + formatDateTime(dateTime, "M-", "zh"));

	}

	public static String formatDateTime(DateTime dateTime, String style,
			String lang) {
		DateTimeFormatter formatter = DateTimeFormat.forStyle(style)
				.withLocale(new Locale(lang));
		return dateTime.toString(formatter);
	}

	/**
	 * 演示日期的加减以及计算日期间的间隔，可使用任意时间单位进行加减和计算间隔.
	 */

	public void daysPlusAndMinusBetweenAndBetweenx() {
		DateTime now = new DateTime();
		DateTime birthDate = now.minusYears(10);
		// assertEquals(10, Years.yearsBetween(birthDate, new
		// DateTime()).getYears());
		birthDate = now.minusYears(10).plusDays(2);
		// assertEquals(9, Years.yearsBetween(birthDate, new
		// DateTime()).getYears());
	}

	/**
	 * 取得月份的头一天和最后一天. 取得一天的0:00和23:59:59 其他如年，星期的头一天，最后一天同理可证
	 */

	public void beginAndEndOfDates() {
		String dateString = "1978-06-10T12:10:08";
		DateTime dt = new DateTime(dateString);
		DateTime startOfMonth = dt.dayOfMonth().withMinimumValue()
				.withTimeAtStartOfDay();
		System.out.println(startOfMonth.toString());

		DateTime endOfMonth = dt.dayOfMonth().withMaximumValue().millisOfDay()
				.withMaximumValue();
		System.out.println(endOfMonth);
	}

	/**
	 * 根据日期获取前一天
	 */
	public static String getPreDay(String date) {
		return getPreDay(date, null);
	}

	public static String getPreDay(String date, String format) {
		if (StringUtils.isEmpty(date))
			return null;
		if (org.apache.commons.lang3.StringUtils.isEmpty(format)) {
			format = "yyyy-MM-dd";
		}
		DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
		DateTime dt = fmt.parseDateTime(date);
		return dt.minusDays(1).toString(fmt);
	}

	public static String getPreDay(String date, int d) {
		DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
		DateTime dt = fmt.parseDateTime(date);
		return dt.minusDays(d).toString(fmt);
	}
	
	public static String getPreDay() {
		DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
		DateTime dt = DateTime.now();
		return dt.minusDays(1).toString(fmt);
	}
	
	public static String getToday() {
		DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
		DateTime dt = DateTime.now();
		return dt.toString(fmt);
	}
	

	/**
	 * 根据日期获取后一天
	 */
	public static String getNextDay(String date) {
		return getNextDay(date, null);
	}

	public static String getNextDay(String date, String format) {
		if (StringUtils.isEmpty(date))
			return null;
		if (org.apache.commons.lang3.StringUtils.isEmpty(format)) {
			format = "yyyy-MM-dd";
		}
		DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
		DateTime dt = fmt.parseDateTime(date);
		return dt.plusDays(1).toString(fmt);
	}

	public static String getNextDay(String date, int days) {
		return getNextDay(date, "yyyy-MM-dd", days);
	}

	public static String getNextDay(String date, String format, int days) {
		if (StringUtils.isEmpty(date))
			return null;
		if (org.apache.commons.lang3.StringUtils.isEmpty(format)) {
			format = "yyyy-MM-dd";
		}
		DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
		DateTime dt = fmt.parseDateTime(date);
		
		if (days < 0) {
			return dt.minusDays(days*-1).toString(fmt);
		}else if (days > 0) {
			return dt.plusDays(days).toString(fmt);
		} else {
			return date;
		}

	}
	
	public static String getNextDay() {
		DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
		DateTime dt = DateTime.now();
		return dt.plusDays(1).toString(fmt);
	}

	/**
	 * 比较两个日期大小
	 */
	public static boolean beforeDate(String date1, String date2) {
		DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
		DateTime dt1 = fmt.parseDateTime(date1);
		DateTime dt2 = fmt.parseDateTime(date2);
		return dt1.isBefore(dt2.getMillis());
	}

	public static boolean afterDate(String date1, String date2) {
		DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
		DateTime dt1 = fmt.parseDateTime(date1);
		DateTime dt2 = fmt.parseDateTime(date2);
		return dt1.isAfter(dt2.getMillis());
	}

	public static String getTimeString(String date) {
		if (StringUtils.isEmpty(date))
			date = "9999-12-31";
		return date;
	}

	/**
	 * 月第一天是周几
	 * 
	 * @param dateString
	 * @return
	 */
	public static int firstDayWeekOfMonth(String dateString) {
		DateTime dt = new DateTime(dateString);
		DateTime startOfMonth = dt.dayOfMonth().withMinimumValue()
				.withTimeAtStartOfDay();
		return startOfMonth.getDayOfWeek();
	}
	
	public static int dayWeekOfMonth(String dateString) {
		DateTime dt = new DateTime(dateString);
		return dt.getDayOfWeek();
	}

	/**
	 * 当月最后一日几号 天数
	 * 
	 * @param dateString
	 * @return
	 */
	public static int endOfMonthDay(String dateString) {
		DateTime dt = new DateTime(dateString);
		DateTime endOfMonth = dt.dayOfMonth().withMaximumValue();
		return endOfMonth.getDayOfMonth();
	}

	/**
	 * 前一月
	 * 
	 * @param dateString
	 * @return
	 */
	public static String preOfMonth(String dateString) {
		DateTime dt = new DateTime(dateString);
		DateTime endOfMonth = dt.minusMinutes(1).dayOfMonth()
				.withMaximumValue();
		return endOfMonth.toString("yyyy-MM");
	}

	public static String nextOfMonth(String dateString) {
		DateTime dt = new DateTime(dateString);
		DateTime endOfMonth = dt.plusMonths(1).dayOfMonth().withMaximumValue();
		return endOfMonth.toString("yyyy-MM");
	}

	/**
	 * 获取指定月的所有指定周天 1 2 3 4 5 6 7 周一：Monday 周二：Tuesday 周三：Wendesday 周四：Thursday
	 * 周五：Friday 周六：Saturday 周日：Sunday
	 * 
	 * @param dateString
	 * @param weekDay
	 * @return
	 */
	public static Map<String, List<String>> monthWeekDay(String dateString) {
		Map<String, List<String>> monthWeek = new HashMap<String, List<String>>();

		DateTime dt = new DateTime(dateString);
		DateTime startOfMonth = dt.dayOfMonth().withMinimumValue()
				.withTimeAtStartOfDay();

		DateTime endOfMonth = dt.dayOfMonth().withMaximumValue();
		int monthDays = endOfMonth.getDayOfMonth();
		// System.out.println(startOfMonth.toString("yyyy-MM-dd"));
		List<String> listMonday = new ArrayList<String>();
		List<String> listTuesday = new ArrayList<String>();
		List<String> listWendesday = new ArrayList<String>();
		List<String> listThursday = new ArrayList<String>();
		List<String> listFriday = new ArrayList<String>();
		List<String> listSaturday = new ArrayList<String>();
		List<String> listSunday = new ArrayList<String>();
		for (int i = 0; i < monthDays; i++) {
			DateTime temp = startOfMonth.plusDays(i);
			String date = temp.toString("yyyy-MM-dd");
			switch (temp.getDayOfWeek()) {
			case 1:
				listMonday.add(date);
				break;
			case 2:
				listTuesday.add(date);
				break;
			case 3:
				listWendesday.add(date);
				break;
			case 4:
				listThursday.add(date);
				break;
			case 5:
				listFriday.add(date);
				break;
			case 6:
				listSaturday.add(date);
				break;
			case 7:
				listSunday.add(date);
				break;
			default:
				break;
			}

			monthWeek.put("Monday", listMonday);
			monthWeek.put("Tuesday", listTuesday);
			monthWeek.put("Wendesday", listWendesday);
			monthWeek.put("Thursday", listThursday);
			monthWeek.put("Friday", listFriday);
			monthWeek.put("Saturday", listSaturday);
			monthWeek.put("Sunday", listSunday);

		}

		return monthWeek;
	}
	
	public static int getHour() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.HOUR_OF_DAY);
	}
}
